
using System;

using Anculus.Core;

using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Client.GtkGui;
using Galaxium.Protocol.Xmpp.Library;
using Galaxium.Protocol.Xmpp.Library.Utility;

namespace Galaxium.Protocol.Xmpp.GtkGui
{
	internal static class XmppActivityPreProcessor
	{
		public static void OnReceivedMessageActivity (object sender, ReceivedMessageActivity activity)
		{
			// NEEDINFO: shouldn't this be handled upstream?
			if (sender is XmppConversation && !(sender as XmppConversation).Active)
				SoundSetUtility.Play (Sound.MessageReceivedNew);
		}
		
		public static void OnContactAddedActivity (object sender, ContactAddedActivity activity)
		{
			var contact = activity.Contact;
			
			string summary = GLib.Markup.EscapeText (contact.InternalContact.Jid)
				+ " was added to your list";
			
			var body = String.Empty;
			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);
			GtkActivityPreProcessor.GenerateNotification (activity, "contact_added",
			                                              summary, body, avatar);
		}
		
		public static void OnContactRemovedActivity (object sender, ContactRemovedActivity activity)
		{
			string summary = GLib.Markup.EscapeText (activity.Jid) + " was removed from your list";
			
			var body = String.Empty;
			var avatar = IconUtility.GetIcon ("galaxium-offline", IconSizes.Large);
			GtkActivityPreProcessor.GenerateNotification (activity, "contact_removed",
			                                              summary, body, avatar);
		}
		
		public static void OnMessageReceivedActivity (object sender, MessageReceivedActivity activity)
		{
			var contact = activity.Contact;
			
			string summary = GLib.Markup.EscapeText (contact.DisplayIdentifier)
				+ " send you a message";
			
			var body = GLib.Markup.EscapeText (activity.Subject);
			// FIXME: replace the image with a message picture
			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);
			GtkActivityPreProcessor.GenerateNotification (activity, "msg_received",
			                                              summary, body, avatar);
			SoundSetUtility.Play (Sound.NewMailReceived);
		}

		public static bool IsOffline (XmppPresence presence)
		{
			return presence == XmppPresence.Offline
				|| presence == XmppPresence.Unknown
				|| presence == XmppPresence.Error;
		}
		
		public static void OnStatusChangedActivity (object sender, StatusChangedActivity activity)
		{
			if (activity.Previous == activity.Contact.Presence
			    && activity.Previous == XmppPresence.Offline) return;
			
			var login = IsOffline (activity.Previous) && !IsOffline (activity.Contact.Presence);
			var logout = !IsOffline (activity.Previous) && IsOffline (activity.Contact.Presence);
			var change = !IsOffline (activity.Previous) && !IsOffline (activity.Contact.Presence);

			if (!(login || logout || change)) return;
			
			string summary;
			
			var contact = activity.Contact;
			var name = GLib.Markup.EscapeText (contact.DisplayIdentifier);
			var item_status = StatusMethods.GetStatus (contact.InternalContact);
			var status = StatusMethods.GetHumanRepresentation (item_status);
			
			if (login) {
				SoundSetUtility.Play (Sound.ContactSignOn);
				summary = name + " logged in";
			} else if (logout) {
				SoundSetUtility.Play (Sound.ContactSignOff);
				summary = name + " logged out";
			} else {
				summary = name + " is now " + status;
			}
			
			var description = contact.InternalContact.MainPresence.GetDescription ();
			if (description != null)
				description = description.Trim ();
			
			var body = description;

			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);
			// TODO: presence emblems
			
			
			// FIXME: Sometimes body is empty or null here. can't generate a notification with that.
			// Why are we making our own custom notification here instead of using the default one?
			if (!String.IsNullOrEmpty (body))
				GtkActivityPreProcessor.GenerateNotification (activity, "status_change", summary, body, avatar);
		}
		
		public static void OnSubscriptionApprovedActivity (object sender,
		                                            SubscriptionApprovedActivity activity)
		{
			string summary = "Subscription change";
			
			var contact = activity.Contact;
			
			var body = String.Format ("You are now allowed to see {0}'s status.",
			                          GLib.Markup.EscapeText (contact.DisplayIdentifier));

			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);

			GtkActivityPreProcessor.GenerateNotification (activity, "subs_granted",
			                                              summary, body, avatar);
		}
		
		public static void OnSubscriptionDeclinedActivity (object sender,
		                                            SubscriptionDeclinedActivity activity)
		{
			string summary = "Subscription change";
			
			var contact = activity.Contact;
			
			var body = String.Format ("You are now forbidden to see {0}'s status.",
			                          GLib.Markup.EscapeText (contact.DisplayIdentifier));

			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);

			GtkActivityPreProcessor.GenerateNotification (activity, "subs_declined",
			                                              summary, body, avatar);
		}
		
		public static void OnSubscriptionRequestedActivity (object sender,
		                                             SubscriptionRequestedActivity activity)
		{
			string summary = "Subscription requested";
			
			var contact = activity.Contact;
			
			var body = String.Format ("{0} is requesting an approval to see your status.",
			                          GLib.Markup.EscapeText (contact.DisplayIdentifier));

			var avatar = GtkActivityPreProcessor.GenerateContactImage (activity.Contact);

			GtkActivityPreProcessor.GenerateNotification (activity, "subs_request",
			                                              summary, body, avatar);
		}
		
	}
}
